home *** CD-ROM | disk | FTP | other *** search
/ The Atari Compendium / The Atari Compendium (Toad Computers) (1994).iso / files / prgtools / mint / shells / tcshsrc.zoo / tcsh / tc.os.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-11-09  |  26.1 KB  |  1,132 lines

  1. /* $Header: /home/hyperion/mu/christos/src/sys/tcsh-6.00/RCS/tc.os.c,v 3.6 1991/07/18 15:24:09 christos Exp $ */
  2. /*
  3.  * tc.os.c: OS Dependent builtin functions
  4.  */
  5. /*-
  6.  * Copyright (c) 1980, 1991 The Regents of the University of California.
  7.  * All rights reserved.
  8.  *
  9.  * Redistribution and use in source and binary forms, with or without
  10.  * modification, are permitted provided that the following conditions
  11.  * are met:
  12.  * 1. Redistributions of source code must retain the above copyright
  13.  *    notice, this list of conditions and the following disclaimer.
  14.  * 2. Redistributions in binary form must reproduce the above copyright
  15.  *    notice, this list of conditions and the following disclaimer in the
  16.  *    documentation and/or other materials provided with the distribution.
  17.  * 3. All advertising materials mentioning features or use of this software
  18.  *    must display the following acknowledgement:
  19.  *    This product includes software developed by the University of
  20.  *    California, Berkeley and its contributors.
  21.  * 4. Neither the name of the University nor the names of its contributors
  22.  *    may be used to endorse or promote products derived from this software
  23.  *    without specific prior written permission.
  24.  *
  25.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  26.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  27.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  28.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  29.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  30.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  31.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  32.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  33.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  34.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  35.  * SUCH DAMAGE.
  36.  */
  37. #include "config.h"
  38. RCSID("$Id: tc.os.c,v 3.6 1991/07/18 15:24:09 christos Exp $")
  39.  
  40. #include "sh.h"
  41. #include "tw.h"
  42. #include "ed.h"
  43. #include "ed.defns.h"        /* for the function names */
  44.  
  45. #ifdef titan
  46. int     end;
  47. #endif                /* titan */
  48.  
  49. /***
  50.  *** MACH
  51.  ***/
  52.  
  53. #ifdef MACH
  54. /* dosetpath -- setpath built-in command
  55.  *
  56.  **********************************************************************
  57.  * HISTORY
  58.  * 08-May-88  Richard Draves (rpd) at Carnegie-Mellon University
  59.  *    Major changes to remove artificial limits on sizes and numbers
  60.  *    of paths.
  61.  *
  62.  **********************************************************************
  63.  */
  64.  
  65. #ifdef MACH
  66. static Char STRCPATH[] = {'C', 'P', 'A', 'T', 'H', '\0'};
  67. static Char STRLPATH[] = {'L', 'P', 'A', 'T', 'H', '\0'};
  68. static Char STRMPATH[] = {'M', 'P', 'A', 'T', 'H', '\0'};
  69. static Char STREPATH[] = {'E', 'P', 'A', 'T', 'H', '\0'};
  70. #endif                /* MACH */
  71.  
  72. static Char *syspaths[] = {STRPATH, STRCPATH, STRLPATH, STRMPATH, STREPATH, 0};
  73. #define LOCALSYSPATH    "/usr/cs"
  74.  
  75. /*ARGSUSED*/
  76. void
  77. dosetpath(arglist, c)
  78.     Char  **arglist;
  79.     struct command *c;
  80. {
  81.     extern char *getenv();
  82.  
  83.     Char  **pathvars, **cmdargs;
  84.     Char  **paths;
  85.     char  **spaths, **cpaths, **cmds;
  86.     char   *tcp;
  87.     unsigned int npaths, ncmds;
  88.     int     i, sysflag;
  89.  
  90.     for (i = 1; arglist[i] && (arglist[i][0] != '-'); i++);
  91.     npaths = i - 1;
  92.  
  93.     cmdargs = &arglist[i];
  94.     for (; arglist[i]; i++);
  95.     ncmds = i - npaths - 1;
  96.  
  97.     if (npaths) {
  98.     sysflag = 0;
  99.     pathvars = &arglist[1];
  100.     }
  101.     else {
  102.     sysflag = 1;
  103.     npaths = (sizeof syspaths / sizeof *syspaths) - 1;
  104.     pathvars = syspaths;
  105.     }
  106.  
  107.     /* note that npaths != 0 */
  108.  
  109.     spaths = (char **) xmalloc(npaths * sizeof *spaths);
  110.     setzero((char *) spaths, npaths * sizeof *spaths);
  111.     paths = (Char **) xmalloc((npaths + 1) * sizeof *paths);
  112.     setzero((char *) paths, (npaths + 1) * sizeof *paths);
  113.     cpaths = (char **) xmalloc((npaths + 1) * sizeof *cpaths);
  114.     setzero((char *) cpaths, (npaths + 1) * sizeof *cpaths);
  115.     cmds = (char **) xmalloc((ncmds + 1) * sizeof *cmds);
  116.     setzero((char *) cmds, (ncmds + 1) * sizeof *cmds);
  117.     for (i = 0; i < npaths; i++) {
  118.     char   *val = getenv(short2str(pathvars[i]));
  119.  
  120.     if (val == NULL)
  121.         val = "";
  122.  
  123.     spaths[i] = xmalloc((Strlen(pathvars[i]) + strlen(val)
  124.                  + 2) * sizeof **spaths);
  125.     (void) strcpy(spaths[i], short2str(pathvars[i]));
  126.     (void) strcat(spaths[i], "=");
  127.     (void) strcat(spaths[i], val);
  128.     cpaths[i] = spaths[i];
  129.     }
  130.  
  131.     for (i = 0; i < ncmds; i++) {
  132.     Char   *val = globone(cmdargs[i], G_ERROR);
  133.  
  134.     if (val == NOSTR)
  135.         goto abortpath;
  136.     cmds[i] = xmalloc(Strlen(val) + 1);
  137.     (void) strcpy(cmds[i], short2str(val));
  138.     }
  139.  
  140.     if (setpath(cpaths, cmds, LOCALSYSPATH, sysflag, 1) < 0) {
  141. abortpath:
  142.     if (spaths) {
  143.         for (i = 0; i < npaths; i++)
  144.         if (spaths[i])
  145.             xfree((ptr_t) spaths[i]);
  146.         xfree((ptr_t) spaths);
  147.     }
  148.     if (paths) {
  149.         for (i = 0; i < npaths; i++)
  150.         if (paths[i])
  151.             xfree((ptr_t) paths[i]);
  152.         xfree((ptr_t) paths);
  153.     }
  154.     if (cpaths)
  155.         xfree((ptr_t) cpaths);
  156.     if (cmds) {
  157.         for (i = 0; i < ncmds; i++)
  158.         if (cmds[i])
  159.             xfree((ptr_t) cmds[i]);
  160.         xfree((ptr_t) cmds);
  161.     }
  162.  
  163.     for (i = 0; i < npaths; i++) {
  164.         paths[i] = SAVE(cpaths[i]);
  165.         xfree((ptr_t) cpaths[i]);
  166.     }
  167.     return;
  168.     }
  169.  
  170.     for (i = 0; i < npaths; i++) {
  171.     Char   *val;
  172.  
  173.     for (val = paths[i]; val && *val && *val != '='; val++);
  174.     if (val && *val == '=') {
  175.         *val++ = '\0';
  176.         setenv(paths[i], val);
  177.         if (Strcmp(paths[i], STRPATH) == 0) {
  178.         importpath(val);
  179.         if (havhash)
  180.             dohash(NULL, NULL);
  181.         }
  182.         *--val = '=';
  183.     }
  184.     }
  185. }
  186. #endif /* MACH */
  187.  
  188. /***
  189.  *** AIX
  190.  ***/
  191. #ifdef TCF
  192. /* ARGSUSED */
  193. void
  194. dogetxvers(v, c)
  195.     Char  **v;
  196.     struct command *c;
  197. {
  198.     char    xvers[MAXPATHLEN];
  199.  
  200.     if (getxvers(xvers, MAXPATHLEN) == -1)
  201.     stderror(ERR_SYSTEM, "getxvers", strerror(errno));
  202.     xprintf("%s\n", xvers);
  203.     flush();
  204. }
  205.  
  206. /*ARGSUSED*/
  207. void
  208. dosetxvers(v, c)
  209.     Char  **v;
  210.     struct command *c;
  211. {
  212.     char   *xvers;
  213.  
  214.     ++v;
  215.     if (!*v || *v[0] == '\0')
  216.     xvers = "";
  217.     else
  218.     xvers = short2str(*v);
  219.     if (setxvers(xvers) == -1)
  220.     stderror(ERR_SYSTEM, "setxvers", strerror(errno));
  221. }
  222.  
  223. #include <sf.h>
  224. #ifdef _AIXPS2
  225. # define XC_PDP11    0x01
  226. # define XC_23        0x02
  227. # define XC_Z8K        0x03
  228. # define XC_8086    0x04
  229. # define XC_68K        0x05
  230. # define XC_Z80        0x06
  231. # define XC_VAX        0x07
  232. # define XC_16032    0x08
  233. # define XC_286        0x09
  234. # define XC_386        0x0a
  235. # define XC_S370    0x0b
  236. #else
  237. # include <sys/x.out.h>
  238. #endif /* _AIXPS2 */
  239.  
  240. static struct xc_cpu_t {
  241.     short   xc_id;
  242.     char   *xc_name;
  243. }       xcpu[] =
  244. {
  245.     { XC_PDP11,    "pdp11"   },
  246.     { XC_23,    "i370"    },
  247.     { XC_Z8K,    "z8000"   },
  248.     { XC_8086,    "i86"      },
  249.     { XC_68K,    "mc68000" },
  250.     { XC_Z80,    "x80"      },
  251.     { XC_VAX,    "vax"      },
  252.     { XC_16032,    "ns16032" },
  253.     { XC_286,    "i286"      },
  254.     { XC_386,    "i386"      },
  255.     { XC_S370,    "xa370"      },
  256.     { 0,    NULL      }
  257. };
  258.  
  259. /*
  260.  * our local hack table, stolen from x.out.h
  261.  */
  262. static char *
  263. getxcode(xcid)
  264.     short   xcid;
  265. {
  266.     int     i;
  267.  
  268.     for (i = 0; xcpu[i].xc_name != NULL; i++)
  269.     if (xcpu[i].xc_id == xcid)
  270.         return (xcpu[i].xc_name);
  271.     return (NULL);
  272. }
  273.  
  274. static short
  275. getxid(xcname)
  276.     char   *xcname;
  277. {
  278.     int     i;
  279.  
  280.     for (i = 0; xcpu[i].xc_name != NULL; i++)
  281.     if (strcmp(xcpu[i].xc_name, xcname) == 0)
  282.         return (xcpu[i].xc_id);
  283.     return ((short) -1);
  284. }
  285.  
  286.  
  287. /*ARGSUSED*/
  288. void
  289. dogetspath(v, c)
  290.     Char  **v;
  291.     struct command *c;
  292. {
  293.     int     i, j;
  294.     sitepath_t p[MAXSITE];
  295.     struct sf *st;
  296.     static char *local = "LOCAL ";
  297.  
  298.     if ((j = getspath(p, MAXSITE)) == -1)
  299.     stderror(ERR_SYSTEM, "getspath", strerror(errno));
  300.     for (i = 0; i < j && (p[i] & SPATH_CPU) != NOSITE; i++) {
  301.     if (p[i] & SPATH_CPU) {
  302.         if ((p[i] & SPATH_MASK) == NULLSITE)
  303.         xprintf(local);
  304.         else if ((st = sfxcode((short) (p[i] & SPATH_MASK))) != NULL)
  305.         xprintf("%s ", st->sf_ctype);
  306.         else {
  307.         char   *xc = getxcode(p[i] & SPATH_MASK);
  308.  
  309.         if (xc != NULL)
  310.             xprintf("%s ", xc);
  311.         else
  312.             xprintf("*cpu %d* ", (int) (p[i] & SPATH_MASK));
  313.         /* 
  314.          * BUG in the aix code... needs that cause if
  315.          * sfxcode fails once it fails for ever 
  316.          */
  317.         endsf();    
  318.         }
  319.     }
  320.     else {
  321.         if (p[i] == NULLSITE)
  322.         xprintf(local);
  323.         else if ((st = sfnum(p[i])) != NULL)
  324.         xprintf("%s ", st->sf_sname);
  325.         else
  326.         xprintf("*site %d* ", (int) (p[i] & SPATH_MASK));
  327.     }
  328.     }
  329.     xprintf("\n");
  330.     flush();
  331. }
  332.  
  333. /*ARGSUSED*/
  334. void
  335. dosetspath(v, c)
  336.     Char  **v;
  337.     struct command *c;
  338. {
  339.     int     i;
  340.     short   j;
  341.     char   *s;
  342.     sitepath_t p[MAXSITE];
  343.     struct sf *st;
  344.  
  345.     for (i = 0, v++; *v && *v[0] != '\0'; v++, i++) {
  346.     s = short2str(*v);
  347.     if (Isdigit(*s))
  348.         p[i] = atoi(s);
  349.     else if (strcmp(s, "LOCAL") == 0)
  350.         p[i] = NULLSITE;
  351.     else if ((st = sfctype(s)) != NULL)
  352.         p[i] = SPATH_CPU | st->sf_ccode;
  353.     else if ((j = getxid(s)) != -1)
  354.         p[i] = SPATH_CPU | j;
  355.     else if ((st = sfname(s)) != NULL)
  356.         p[i] = st->sf_id;
  357.     else {
  358.         setname(s);
  359.         stderror(ERR_NAME | ERR_STRING, "Bad cpu/site name");
  360.     }
  361.     if (i == MAXSITE - 1)
  362.         stderror(ERR_NAME | ERR_STRING, "Site path too long");
  363.     }
  364.     if (setspath(p, i) == -1)
  365.     stderror(ERR_SYSTEM, "setspath", strerror(errno));
  366. }
  367.  
  368. /* sitename():
  369.  *    Return the site name where the process is running
  370.  */
  371. char   *
  372. sitename(pid)
  373.     pid_t   pid;
  374. {
  375.     siteno_t ss;
  376.     struct sf *st;
  377.  
  378.     if ((ss = site(pid)) == -1 || (st = sfnum(ss)) == NULL)
  379.     return ("unknown");
  380.     else
  381.     return (st->sf_sname);
  382. }
  383.  
  384. static int
  385. migratepid(pid, new_site)
  386.     pid_t   pid;
  387.     siteno_t new_site;
  388. {
  389.     struct sf *st;
  390.     int     need_local;
  391.  
  392.     need_local = (pid == 0) || (pid == getpid());
  393.  
  394.     if (kill3((pid_t) pid, SIGMIGRATE, new_site) < 0) {
  395.     xprintf("%d: %s\n", pid, strerror(errno));
  396.     return (-1);
  397.     }
  398.  
  399.     if (need_local) {
  400.     if ((new_site = site(0)) == -1) {
  401.         xprintf("site: %s\n", strerror(errno));
  402.         return (-1);
  403.     }
  404.     if ((st = sfnum(new_site)) == NULL) {
  405.         xprintf("%d: Site not found\n", new_site);
  406.         return (-1);
  407.     }
  408.     if (setlocal(st->sf_local, strlen(st->sf_local)) == -1) {
  409.         xprintf("setlocal: %s: %s\n", st->sf_local, strerror(errno));
  410.         return (-1);
  411.     }
  412.     }
  413.     return (0);
  414. }
  415.  
  416. /*ARGSUSED*/
  417. void
  418. domigrate(v, c)
  419.     Char  **v;
  420.     struct command *c;
  421. {
  422.     struct sf *st;
  423.     char   *s;
  424.     Char   *cp;
  425.     struct process *pp;
  426.     int     pid, err1 = 0;
  427.     siteno_t new_site = 0;
  428.     sigmask_t omask;
  429.  
  430. #ifdef BSDSIGS
  431.     omask = sigmask(SIGCHLD);
  432.     if (setintr)
  433.     omask |= sigmask(SIGINT);
  434.     omask = sigblock(omask) & ~omask;
  435. #else
  436.     if (setintr)
  437.     (void) sighold(SIGINT);
  438.     (void) sighold(SIGCHLD);
  439. #endif /* BSDSIGS */
  440.  
  441.     ++v;
  442.     if (*v[0] == '-') {
  443.     /*
  444.      * Do the -site.
  445.      */
  446.     s = short2str(&v[0][1]);
  447.     if ((st = sfname(s)) == NULL) {
  448.         setname(s);
  449.         stderror(ERR_NAME | ERR_STRING, "Site not found");
  450.     }
  451.     new_site = st->sf_id;
  452.     ++v;
  453.     }
  454.  
  455.     if (!*v || *v[0] == '\0') {
  456.     if (migratepid(0, new_site) == -1)
  457.         err1++;
  458.     }
  459.     else {
  460.     gflag = 0, tglob(v);
  461.     if (gflag) {
  462.         v = globall(v);
  463.         if (v == 0)
  464.         stderror(ERR_NAME | ERR_NOMATCH);
  465.     }
  466.     else {
  467.         v = gargv = saveblk(v);
  468.         trim(v);
  469.     }
  470.  
  471.     while (v && (cp = *v)) {
  472.         if (*cp == '%') {
  473.         pp = pfind(cp);
  474.         if (kill3((pid_t) - pp->p_jobid, SIGMIGRATE, new_site) < 0) {
  475.             xprintf("%s: %s\n", short2str(cp), strerror(errno));
  476.             err1++;
  477.         }
  478.         }
  479.         else if (!(Isdigit(*cp) || *cp == '-'))
  480.         stderror(ERR_NAME | ERR_JOBARGS);
  481.         else {
  482.         pid = atoi(short2str(cp));
  483.         if (migratepid(pid, new_site) == -1)
  484.             err1++;
  485.         }
  486.         v++;
  487.     }
  488.     if (gargv)
  489.         blkfree(gargv), gargv = 0;
  490.     }
  491.  
  492. done:
  493. #ifdef BSDSIGS
  494.     (void) sigsetmask(omask);
  495. #else
  496.     (void) sigrelse(SIGCHLD);
  497.     if (setintr)
  498.     (void) sigrelse(SIGINT);
  499. #endif /* BSDSIGS */
  500.     if (err1)
  501.     stderror(ERR_SILENT);
  502. }
  503.  
  504. #endif /* TCF */
  505.  
  506. /***
  507.  *** CONVEX Warps.
  508.  ***/
  509.  
  510. #ifdef WARP
  511. /*
  512.  * handle the funky warping of symlinks
  513.  */
  514. #include <warpdb.h>
  515. #include <sys/warp.h>
  516.  
  517. static jmp_buf sigsys_buf;
  518.  
  519. static  sigret_t
  520. catch_sigsys()
  521. {
  522.     longjmp(sigsys_buf, 1);
  523. }
  524.  
  525.  
  526. /*ARGSUSED*/
  527. void
  528. dowarp(v, c)
  529.     Char  **v;
  530.     struct command *c;
  531. {
  532.     int     warp, oldwarp;
  533.     struct warpent *we;
  534.     void    (*old_sigsys_handler) () = 0;
  535.     char   *newwarp;
  536.  
  537.     if (setjmp(sigsys_buf)) {
  538.     signal(SIGSYS, old_sigsys_handler);
  539.     stderror(ERR_NAME | ERR_STRING, 
  540.          "You're trapped in a universe you never made");
  541.     return;
  542.     }
  543.     old_sigsys_handler = signal(SIGSYS, catch_sigsys);
  544.  
  545.     warp = getwarp();
  546.  
  547.     v++;
  548.     if (*v == 0) {        /* display warp value */
  549.     if (warp < 0)
  550.         stderror(ERR_NAME | ERR_STRING, "Getwarp failed");
  551.     we = getwarpbyvalue(warp);
  552.     if (we)
  553.         printf("%s\n", we->w_name);
  554.     else
  555.         printf("%d\n", warp);
  556.     }
  557.     else {            /* set warp value */
  558.     oldwarp = warp;
  559.     newwarp = short2str(*v);
  560.     if (Isdigit(*v[0]))
  561.         warp = atoi(newwarp);
  562.     else {
  563.         we = getwarpbyname(newwarp);
  564.         if (we)
  565.         warp = we->w_value;
  566.         else
  567.         warp = -1;
  568.     }
  569.     if ((warp < 0) || (warp >= WARP_MAXLINK))
  570.         stderror(ERR_NAME | ERR_STRING, "Invalid warp");
  571.     if ((setwarp(warp) < 0) || (getwarp() != warp)) {
  572.         (void) setwarp(oldwarp);
  573.         stderror(ERR_NAME | ERR_STRING, "Setwarp failed");
  574.     }
  575.     }
  576.     signal(SIGSYS, old_sigsys_handler);
  577.     return;
  578. }
  579. #endif /* WARP */
  580.  
  581. /***
  582.  *** Masscomp
  583.  ***/
  584. /* Added, DAS DEC-90. */
  585. #ifdef masscomp
  586. /*ARGSUSED*/
  587. void
  588. douniverse(v, c)
  589.     register Char **v;
  590.     struct command *c;
  591. {
  592.     register Char *cp = v[1];
  593.     char    ubuf[100];
  594.  
  595.     if (cp == 0) {
  596.     (void) getuniverse(ubuf);
  597.     xprintf("%s\n", ubuf);
  598.     }
  599.     else if (*cp == '\0' || setuniverse(short2str(cp)) != 0)
  600.     stderror(ERR_NAME | ERR_STRING, "Illegal universe");
  601. }
  602. #endif /* masscomp */
  603.  
  604.  
  605. #ifdef _SEQUENT_
  606. /*
  607.  * Compute the difference in process stats.
  608.  */
  609. void
  610. pr_stat_sub(p2, p1, pr)
  611.     struct process_stats *p2, *p1, *pr;
  612. {
  613.     pr->ps_utime.tv_sec = p2->ps_utime.tv_sec - p1->ps_utime.tv_sec;
  614.     pr->ps_utime.tv_usec = p2->ps_utime.tv_usec - p1->ps_utime.tv_usec;
  615.     if (pr->ps_utime.tv_usec < 0) {
  616.     pr->ps_utime.tv_sec -= 1;
  617.     pr->ps_utime.tv_usec += 1000000;
  618.     }
  619.     pr->ps_stime.tv_sec = p2->ps_stime.tv_sec - p1->ps_stime.tv_sec;
  620.     pr->ps_stime.tv_usec = p2->ps_stime.tv_usec - p1->ps_stime.tv_usec;
  621.     if (pr->ps_stime.tv_usec < 0) {
  622.     pr->ps_stime.tv_sec -= 1;
  623.     pr->ps_stime.tv_usec += 1000000;
  624.     }
  625.  
  626.     pr->ps_maxrss = p2->ps_maxrss - p1->ps_maxrss;
  627.     pr->ps_pagein = p2->ps_pagein - p1->ps_pagein;
  628.     pr->ps_reclaim = p2->ps_reclaim - p1->ps_reclaim;
  629.     pr->ps_zerofill = p2->ps_zerofill - p1->ps_zerofill;
  630.     pr->ps_pffincr = p2->ps_pffincr - p1->ps_pffincr;
  631.     pr->ps_pffdecr = p2->ps_pffdecr - p1->ps_pffdecr;
  632.     pr->ps_swap = p2->ps_swap - p1->ps_swap;
  633.     pr->ps_syscall = p2->ps_syscall - p1->ps_syscall;
  634.     pr->ps_volcsw = p2->ps_volcsw - p1->ps_volcsw;
  635.     pr->ps_involcsw = p2->ps_involcsw - p1->ps_involcsw;
  636.     pr->ps_signal = p2->ps_signal - p1->ps_signal;
  637.     pr->ps_lread = p2->ps_lread - p1->ps_lread;
  638.     pr->ps_lwrite = p2->ps_lwrite - p1->ps_lwrite;
  639.     pr->ps_bread = p2->ps_bread - p1->ps_bread;
  640.     pr->ps_bwrite = p2->ps_bwrite - p1->ps_bwrite;
  641.     pr->ps_phread = p2->ps_phread - p1->ps_phread;
  642.     pr->ps_phwrite = p2->ps_phwrite - p1->ps_phwrite;
  643. }
  644.  
  645. #endif /* _SEQUENT_ */
  646.  
  647.  
  648. #ifdef tcgetpgrp
  649. int
  650. xtcgetpgrp(fd)
  651.     int     fd;
  652. {
  653.     int     pgrp;
  654.  
  655.     /* ioctl will handle setting errno correctly. */
  656.     if (ioctl(fd, TIOCGPGRP, (ioctl_t) & pgrp) < 0)
  657.     return (-1);
  658.     return (pgrp);
  659. }
  660.  
  661. #endif    /* tcgetpgrp */
  662.  
  663.  
  664. #ifdef YPBUGS
  665. void
  666. fix_yp_bugs()
  667. {
  668.     char   *mydomain;
  669.  
  670.     /*
  671.      * PWP: The previous version assumed that yp domain was the same as the
  672.      * internet name domain.  This isn't allways true. (Thanks to Mat Landau
  673.      * <mlandau@bbn.com> for the original version of this.)
  674.      */
  675.     if (yp_get_default_domain(&mydomain) == 0) {    /* if we got a name */
  676.     extern void yp_unbind();
  677.  
  678.     yp_unbind(mydomain);
  679.     }
  680. }
  681.  
  682. #endif /* YPBUGS */
  683.  
  684.  
  685. void
  686. osinit()
  687. {
  688.     extern ptr_t membot;
  689.  
  690. #ifndef __MINT__
  691.     membot = (char *) sbrk(0);
  692. #endif
  693.  
  694. #ifdef OREO
  695.     set42sig();
  696.     sigignore(SIGIO);        /* ignore SIGIO */
  697. #endif /* OREO */
  698.  
  699. #ifdef aiws
  700.     {
  701.     struct sigstack inst;
  702.     inst.ss_sp = xmalloc(4192) + 4192;
  703.     inst.ss_onstack = 0;
  704.     sigstack(&inst, NULL);
  705.     }
  706. #endif /* aiws */
  707.  
  708. #ifdef hpux
  709.     (void) sigspace(4192);
  710. #endif    /* hpux */
  711. #ifdef titan
  712.     end = sbrk(0);
  713. #endif    /* titan */
  714.  
  715. #ifdef apollo
  716.     (void) isapad();
  717. #endif
  718. }
  719.  
  720. #ifdef gethostname
  721. #include <sys/utsname.h>
  722.  
  723. int
  724. xgethostname(name, namlen)
  725.     char   *name;
  726.     int     namlen;
  727. {
  728.     int     i, retval;
  729.     struct utsname uts;
  730.  
  731.     retval = uname(&uts);
  732.  
  733. #ifdef DEBUG
  734.     xprintf("sysname:  %s\n", uts.sysname);
  735.     xprintf("nodename: %s\n", uts.nodename);
  736.     xprintf("release:  %s\n", uts.release);
  737.     xprintf("version:  %s\n", uts.version);
  738.     xprintf("machine:  %s\n", uts.machine);
  739. #endif                /* DEBUG */
  740.     i = strlen(uts.nodename) + 1;
  741.     (void) strncpy(name, uts.nodename, i < namlen ? i : namlen);
  742.  
  743.     return retval;
  744. }                /* end gethostname */
  745.  
  746. #endif                /* gethostname */
  747.  
  748.  
  749. #ifdef getwd
  750. static char *strrcpy __P((char *, char *));
  751.  
  752. /* xgetwd():
  753.  *    Return the pathname of the current directory, or return
  754.  *    an error message in pathname.
  755.  */
  756.  
  757. # ifdef hp9000s500
  758. /*
  759.  *  From: Bernd Mohr <mohr@faui77.informatik.uni-erlangen.de>
  760.  *  I also ported the tcsh to the HP9000 Series 500. This computer
  761.  *  is a little bit different than the other HP 9000 computer. It has
  762.  *  a HP Chip instead of a Motorola CPU and it is no "real" UNIX. It runs
  763.  *  HP-UX which is emulated in top of a HP operating system. So, the last
  764.  *  supported version of HP-UX is 5.2 on the HP9000s500. This has two
  765.  *  consequences: it supports no job control and it has a filesystem
  766.  *  without "." and ".." !!!
  767.  */
  768. static int pathsize;            /* pathname length */
  769.  
  770. char *
  771. xgetwd(pathname)
  772.     char *pathname;
  773. {
  774.     char pathbuf[MAXNAMLEN];    /* temporary pathname buffer */
  775.     char *pnptr = &pathbuf[(sizeof pathbuf)-1]; /* pathname pointer */
  776.     char *prepend();        /* prepend dirname to pathname */
  777.     dev_t rdev;            /* root device number */
  778.     DIR *dirp;            /* directory stream */
  779.     ino_t rino;            /* root inode number */
  780.     off_t rsize;            /* root size */
  781.     struct direct *dir;        /* directory entry struct */
  782.     struct stat d ,dd;        /* file status struct */
  783.  
  784.     pathsize = 0;
  785.     *pnptr = '\0';
  786.     stat("/.", &d);
  787.     rdev = d.st_dev;
  788.     rino = d.st_ino;
  789.     rsize = d.st_size;
  790.     for (;;) {
  791.         stat(".", &d);
  792.         if (d.st_ino == rino && d.st_dev == rdev && d.st_size == rsize)
  793.             break;        /* reached root directory */
  794.         if ((dirp = opendir("..")) == NULL) {
  795.                 (void) xsprintf(pathname,
  796.                         "getwd: Cannot open \"..\" (%s)", strerror(errno));
  797.             goto fail;
  798.         }
  799.         if (chdir("..") < 0) {
  800.                 (void) xsprintf(pathname,
  801.                         "getwd: Cannot chdir to \"..\" (%s)", strerror(errno));
  802.             goto fail;
  803.         }
  804.         do {
  805.             if((dir = readdir(dirp)) == NULL) {
  806.                 closedir(dirp);
  807.                     (void) xsprintf(pathname,
  808.                             "getwd: Read error in \"..\" (%s)",
  809.                 strerror(errno));
  810.                 goto fail;
  811.             }
  812.             stat(dir->d_name, &dd);
  813.         } while (dd.st_ino  != d.st_ino  ||
  814.              dd.st_dev  != d.st_dev  ||
  815.              dd.st_size != d.st_size
  816.             );
  817.         closedir(dirp);
  818.         pnptr = prepend("/", prepend(dir->d_name, pnptr));
  819.     }
  820.  
  821.     if (*pnptr == '\0')        /* current dir == root dir */
  822.         strcpy(pathname, "/");
  823.     else {
  824.         strcpy(pathname, pnptr);
  825.         if (chdir(pnptr) < 0) {
  826.                 (void) xsprintf(pathname,
  827.                         "getwd: Cannot change back to \".\" (%s)",
  828.             strerror(errno));
  829.             return (NULL);
  830.         }
  831.     }
  832.     return (pathname);
  833.  
  834. fail:
  835.     chdir(prepend(".", pnptr));
  836.     return (NULL);
  837. }
  838.  
  839. /* prepend():
  840.  *     tacks a directory name onto the front of a pathname.
  841.  */
  842. static char *
  843. prepend(dirname, pathname)
  844.     register char *dirname;
  845.     register char *pathname;
  846. {
  847.     register int i;            /* directory name size counter */
  848.  
  849.     for (i = 0; *dirname != '\0'; i++, dirname++)
  850.         continue;
  851.     if ((pathsize += i) < MAXNAMLEN)
  852.         while (i-- > 0)
  853.             *--pathname = *--dirname;
  854.     return (pathname);
  855. }
  856.  
  857. # else /* ! hp9000s500 */
  858. char   *
  859. xgetwd(pathname)
  860.     char   *pathname;
  861. {
  862.     DIR    *dp;
  863.     struct dirent *d;
  864.  
  865.     struct stat st_root, st_cur, st_next, st_dot;
  866.     char    pathbuf[MAXPATHLEN], nextpathbuf[MAXPATHLEN * 2];
  867.     char   *cur_name_add;
  868.     char   *pathptr, *nextpathptr;
  869.  
  870.     /* find the inode of root */
  871.     if (stat("/", &st_root) == -1) {
  872.     (void) xsprintf(pathname,
  873.             "getwd: Cannot stat \"/\" (%s)", strerror(errno));
  874.     return (NULL);
  875.     }
  876.     pathbuf[MAXPATHLEN - 1] = '\0';
  877.     pathptr = &pathbuf[MAXPATHLEN - 1];
  878.     nextpathbuf[MAXPATHLEN - 1] = '\0';
  879.     cur_name_add = nextpathptr = &nextpathbuf[MAXPATHLEN - 1];
  880.  
  881.     /* find the inode of the current directory */
  882.     if (lstat("./", &st_cur) == -1) {
  883.     (void) xsprintf(pathname,
  884.             "getwd: Cannot stat \".\" (%s)", strerror(errno));
  885.     return (NULL);
  886.     }
  887.     nextpathptr = strrcpy(nextpathptr, "../");
  888.  
  889.     /* Descend to root */
  890.     for (;;) {
  891.  
  892.     /* look if we found root yet */
  893.     if (st_cur.st_ino == st_root.st_ino &&
  894.         st_cur.st_dev == st_root.st_dev) {
  895.         (void) strcpy(pathname, *pathptr != '/' ? "/" : pathptr);
  896.         return (pathname);
  897.     }
  898.  
  899.     /* open the parent directory */
  900.     if ((dp = opendir(nextpathptr)) == NULL) {
  901.         (void) xsprintf(pathname,
  902.                 "getwd: Cannot open directory \"%s\" (%s)",
  903.                 nextpathptr, strerror(errno));
  904.         return (NULL);
  905.     }
  906.  
  907.     /* look in the parent for the entry with the same inode */
  908.     for (d = readdir(dp); d != NULL; d = readdir(dp)) {
  909.         (void) strcpy(cur_name_add, d->d_name);
  910.         if (lstat(nextpathptr, &st_next) == -1) {
  911.         (void) xsprintf(pathname, "getwd: Cannot stat \"%s\" (%s)",
  912.                 d->d_name, strerror(errno));
  913.         return (NULL);
  914.         }
  915.         if (d->d_name[0] == '.' && d->d_name[1] == '\0')
  916.         st_dot = st_next;
  917.  
  918.         /* check if we found it yet */
  919.         if (st_next.st_ino == st_cur.st_ino &&
  920.         st_next.st_dev == st_cur.st_dev) {
  921.         st_cur = st_dot;
  922.         pathptr = strrcpy(pathptr, d->d_name);
  923.         pathptr = strrcpy(pathptr, "/");
  924.         nextpathptr = strrcpy(nextpathptr, "../");
  925.         *cur_name_add = '\0';
  926.         (void) closedir(dp);
  927.         break;
  928.         }
  929.     }
  930.     if (d == NULL) {
  931.         (void) xsprintf(pathname, "getwd: Cannot find \".\" in \"..\"");
  932.         return (NULL);
  933.     }
  934.     }
  935. } /* end getwd */
  936.  
  937. /* strrcpy():
  938.  *    Like strcpy, going backwards and returning the new pointer
  939.  */
  940. static char *
  941. strrcpy(ptr, str)
  942.     register char *ptr, *str;
  943. {
  944.     register int len = strlen(str);
  945.  
  946.     while (len)
  947.     *--ptr = str[--len];
  948.  
  949.     return (ptr);
  950. } /* end strrcpy */
  951. # endif /* hp9000s500 */
  952. #endif /* getwd */
  953.  
  954. #ifdef iconuxv
  955. #include <sys/vendor.h>
  956. #include <sys/bsd_syscall.h>
  957.  
  958. int
  959. vfork()
  960. {
  961.     return sys_local(VEND_ICON_BSD, 66);
  962. }
  963.  
  964. #endif                /* iconuxv */
  965.  
  966. #ifdef apollo
  967. /***
  968.  *** Domain/OS
  969.  ***/
  970. #undef value            /* XXX: Careful here */
  971. #include <apollo/base.h>
  972. #include <apollo/loader.h>
  973. #include <apollo/error.h>
  974.  
  975.  
  976. static char *
  977. apperr(st)
  978.     status_$t *st;
  979. {
  980.     static char buf[BUFSIZ];
  981.     short e_subl, e_modl, e_codel;
  982.     error_$string_t e_sub, e_mod, e_code;
  983.  
  984.     error_$get_text(*st, e_sub, &e_subl, e_mod, &e_modl, e_code, &e_codel);
  985.     e_sub[e_subl] = '\0';
  986.     e_code[e_codel] = '\0';
  987.     e_mod[e_modl] = '\0';
  988.     (void) xsprintf(buf, "%s (%s/%s)", e_code, e_sub, e_mod);
  989.  
  990.     return(buf);
  991. }
  992.  
  993. static int
  994. llib(s)
  995.     Char *s;
  996. {
  997.     short len = Strlen(s);
  998.     status_$t st;
  999.     char *t;
  1000.  
  1001.     loader_$inlib(t = short2str(s), len, &st);
  1002.     if (st.all != status_$ok) 
  1003.     stderror(ERR_SYSTEM, t, apperr(&st));
  1004. }
  1005.  
  1006. /*ARGSUSED*/
  1007. void
  1008. doinlib(v, c)
  1009.     Char **v;
  1010.     struct command *c;
  1011. {
  1012.     setname(short2str(*v++));
  1013.     gflag = 0, tglob(v);
  1014.     if (gflag) {
  1015.     v = globall(v);
  1016.     if (v == 0)
  1017.         stderror(ERR_NAME | ERR_NOMATCH);
  1018.     }
  1019.     else {
  1020.     v = gargv = saveblk(v);
  1021.     trim(v);
  1022.     }
  1023.  
  1024.     while (v && *v) 
  1025.     llib(*v++);
  1026.     if (gargv)
  1027.     blkfree(gargv), gargv = 0;
  1028. }
  1029.  
  1030. int
  1031. getv(v)
  1032.     Char *v;
  1033. {
  1034.     if (eq(v, STRbsd43))
  1035.     return(1);
  1036.     else if (eq(v, STRsys53))
  1037.     return(0);
  1038.     else 
  1039.     stderror(ERR_NAME | ERR_SYSTEM, short2str(v), "Invalid system type");
  1040.     /*NOTREACHED*/
  1041.     return(0);
  1042. }
  1043.  
  1044. /*ARGSUSED*/
  1045. void
  1046. dover(v, c)
  1047.     Char **v;
  1048.     struct command *c;
  1049. {
  1050.     Char *p;
  1051.  
  1052.     setname(short2str(*v++));
  1053.     if (!*v) {
  1054.     if (!(p = Getenv(STRSYSTYPE)))
  1055.         stderror(ERR_NAME | ERR_STRING, "System type is not set");
  1056.     xprintf("%s\n", short2str(p));
  1057.     }
  1058.     else {
  1059.     Setenv(STRSYSTYPE, getv(*v) ? STRbsd43 : STRsys53);
  1060.     dohash(NULL, NULL);
  1061.     }
  1062. }
  1063.  
  1064. /*
  1065.  * Many thanks to rees@citi.umich.edu (Jim Rees) and
  1066.  *                mathys@ssdt-tempe.sps.mot.com (Yves Mathys)
  1067.  * For figuring out how to do this... I could have never done
  1068.  * it without their help.
  1069.  */
  1070. typedef short enum {
  1071.     name_$wdir_type,
  1072.     name_$ndir_type,
  1073.     name_$node_dir_type,
  1074. } name_$dir_type_t;
  1075.  
  1076. /*ARGSUSED*/
  1077. void
  1078. dorootnode(v, c)
  1079.     Char **v;
  1080.     struct command *c;
  1081. {
  1082.     name_$dir_type_t dirtype = name_$node_dir_type;
  1083.     uid_$t uid;
  1084.     status_$t st;
  1085.     char *name;
  1086.     short namelen;
  1087.  
  1088.     setname(short2str(*v++));
  1089.  
  1090.     name = short2str(*v);
  1091.     namelen = strlen(name);
  1092.  
  1093.     name_$resolve(name, &namelen, &uid, &st);
  1094.     if (st.all != status_$ok) 
  1095.     stderror(ERR_SYSTEM, name, apperr(&st));
  1096.     namelen = 0;
  1097.     name_$set_diru(&uid, "", &namelen, &dirtype, &st);
  1098.     if (st.all != status_$ok) 
  1099.     stderror(ERR_SYSTEM, name, apperr(&st));
  1100.     dohash(NULL, NULL);
  1101. }
  1102.  
  1103. int
  1104. isapad()
  1105. {
  1106.     static int res = -1;
  1107.     static status_$t st;
  1108.  
  1109.     if (res == -1) {
  1110.     int strm;
  1111.     if (isatty(0))
  1112.         strm = 0;
  1113.     if (isatty(1))
  1114.         strm = 1;
  1115.     if (isatty(2))
  1116.         strm = 2;
  1117.     else {
  1118.         res = 0;
  1119.         st.all = status_$ok;
  1120.         return(res);
  1121.     }
  1122.     res = stream_$isavt(&strm, &st);
  1123.     res = res ? 1 : 0;
  1124.     }
  1125.     else {
  1126.     if (st.all != status_$ok) 
  1127.         stderror(ERR_SYSTEM, "stream_$isavt", apperr(&st));
  1128.     }
  1129.     return(res);
  1130. }
  1131. #endif
  1132.